/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ferramentas;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;
import org.apache.tomcat.jdbc.pool.PoolProperties;

/**
 *
 * @author Lauro
 */
public class Conexao {

    private static volatile DataSource dsObj;

    /**
     * Initialize Data Source
     */
    private static void initialize() {
        // Create Property 
        try {
            dsObj = CFG.tipoDataSource == CFG.TipoDataSource.BASIC ? getBasicDataSource() : getPoolDataSource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static DataSource getBasicDataSource() throws Exception {
        Properties dsProperties = new Properties();
        dsProperties.setProperty("url", CFG.DB_LOCAL);
        dsProperties.setProperty("driverClassName", "com.mysql.jdbc.Driver");
        dsProperties.setProperty("username", CFG.DB_USUARIO);
        dsProperties.setProperty("password", CFG.DB_SENHA);
        dsProperties.setProperty("maxActive", "" + CFG.MAX_ACTIVE);
        dsProperties.setProperty("minIdle", "0");
        dsProperties.setProperty("maxIdle", "" + CFG.MAX_IDLE_TIME);
        dsProperties.setProperty("maxWait", "" + CFG.MAX_WAIT);
        dsProperties.setProperty("defaultAutoCommit", "false");
        dsProperties.setProperty("defaultTransactionIsolation", "READ_UNCOMMITTED");
        return BasicDataSourceFactory.createDataSource(dsProperties);
    }

    private static DataSource getPoolDataSource() {
        PoolProperties p = new PoolProperties();
        p.setDriverClassName("com.mysql.jdbc.Driver");
        p.setUrl(CFG.DB_LOCAL);
        p.setUsername(CFG.DB_USUARIO);
        p.setPassword(CFG.DB_SENHA);
        p.setDefaultAutoCommit(false);
        p.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
        p.setMaxActive(CFG.MAX_ACTIVE);
        p.setInitialSize(CFG.BD_INITIAL_POOL_SIZE);
        p.setMaxWait(CFG.MAX_WAIT);
        p.setMinIdle(CFG.MIN_IDLE_TIME);
        p.setRemoveAbandonedTimeout(10);
        p.setMinEvictableIdleTimeMillis(10000);
        p.setValidationInterval(30000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setJmxEnabled(false);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(false);
        p.setTestOnReturn(false);
        p.setLogAbandoned(false);
        p.setRemoveAbandoned(false);
        org.apache.tomcat.jdbc.pool.DataSource datasource = new org.apache.tomcat.jdbc.pool.DataSource();
        datasource.setPoolProperties(p);
        return datasource;
    }

    /**
     * Returns DB Connection
     *
     * @return Connection
     * @throws SQLException
     */
    public static Connection getConexao() {
        try {
            // checking for null singleton instance
            if (null == dsObj) { // synchronized over class to make thread safe
                synchronized (Conexao.class) {
                    // double checking for making singleton instance thread safe
                    if (null == dsObj) {
                        initialize();
                    }
                }
            }
            // getting connection from data source
            Connection connection = dsObj.getConnection();
            return connection;
        } catch (SQLException ex) {
            Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    /**
     * Method to close the connection, Statement and Result Set
     *
     * @param conection
     * @param statement
     * @param resultset
     */
    public static void close(Connection conection, Statement statement, ResultSet resultset) {
        try {
            conection.commit();
            if (null != statement) {
                statement.close();
            }
            if (null != resultset) {
                resultset.close();
            }
            if (null != conection) {
                conection.close();
            }
        } catch (SQLException sqle1) {
            sqle1.printStackTrace();
        }
    }

    public static void close(Connection conn, Exception ex) {
        System.out.println(ex);
        try {
            conn.rollback();
        } catch (SQLException ex1) {
            Logger.getLogger(Conexao.class.getName()).log(Level.SEVERE, null, ex1);
        }
        close(conn, null, null);
    }

    public static void close(Connection conn) {
        close(conn, null, null);
    }

    public static void close(Connection conn, Statement st) {
        close(conn, st, null);
    }
}
